package com.tetris.logic;

import com.tetris.block.Block;
import com.tetris.block.Tetromino;
import com.tetris.rule.GameRules;
import com.tetris.rule.ClassicTetrisRules;

import java.util.Random;

/**
 * 游戏逻辑类，处理游戏的核心逻辑
 */
public class TetrisGame {
    private final int width;                // 游戏区域宽度
    private final int height;               // 游戏区域高度
    private final int[][] grid;             // 游戏网格
    private Block currentBlock;             // 当前方块
    private Block nextBlock;                // 下一个方块
    private final GameRules rules;          // 游戏规则
    private int score;                      // 当前分数
    private int highScore;                  // 最高分
    private boolean gameOver;               // 游戏是否结束
    private final Random random;            // 随机数生成器
    
    public TetrisGame(int width, int height) {
        this.width = width;
        this.height = height;
        this.grid = new int[height][width];
        this.rules = new ClassicTetrisRules();
        this.random = new Random();
        this.score = 0;
        this.highScore = loadHighScore();
        this.gameOver = false;
        
        // 初始化游戏
        initializeGame();
    }
    
    // 初始化游戏
    private void initializeGame() {
        // 清空网格
        for (int i = 0; i < height; i++) {
            for (int j = 0; j < width; j++) {
                grid[i][j] = 0;
            }
        }
        
        // 生成新方块
        spawnNewBlock();
    }
    
    // 生成新方块
    private void spawnNewBlock() {
        // 如果没有下一个方块，先生成一个
        if (nextBlock == null) {
            nextBlock = Tetromino.getRandomBlock(width / 2 - 1, 0);
        }
        
        // 将下一个方块设为当前方块
        currentBlock = nextBlock;
        
        // 生成新的下一个方块
        nextBlock = Tetromino.getRandomBlock(width / 2 - 1, 0);
        
        // 检查游戏是否结束
        if (!rules.isValidMove(grid, currentBlock, GameRules.Direction.DOWN)) {
            gameOver = true;
        }
    }
    
    // 移动当前方块
    public boolean moveBlock(GameRules.Direction direction) {
        if (gameOver || currentBlock == null) {
            return false;
        }
        
        if (rules.isValidMove(grid, currentBlock, direction)) {
            currentBlock.move(direction);
            return true;
        }
        
        // 如果是向下移动且无法移动，则固定方块
        if (direction == GameRules.Direction.DOWN) {
            fixBlockToGrid();
            return false;
        }
        
        return false;
    }
    
    // 旋转当前方块
    public boolean rotateBlock(GameRules.Rotation rotation) {
        if (gameOver || currentBlock == null) {
            return false;
        }
        
        if (rules.isValidRotation(grid, currentBlock, rotation)) {
            currentBlock.rotate(rotation);
            return true;
        }
        
        return false;
    }
    
    // 将方块固定到网格
    private void fixBlockToGrid() {
        int[][] shape = currentBlock.getShape();
        int x = currentBlock.getX();
        int y = currentBlock.getY();
        
        for (int i = 0; i < shape.length; i++) {
            for (int j = 0; j < shape[i].length; j++) {
                if (shape[i][j] != 0) {
                    int gridX = x + j;
                    int gridY = y + i;
                    
                    if (gridY >= 0 && gridY < height && gridX >= 0 && gridX < width) {
                        grid[gridY][gridX] = 1;
                    }
                }
            }
        }
        
        // 检查并消除行
        int linesCleared = rules.clearLines(grid);
        
        // 更新分数
        updateScore(linesCleared);
        
        // 生成新方块
        spawnNewBlock();
    }
    
    // 更新分数
    private void updateScore(int linesCleared) {
        score += rules.calculateScore(linesCleared);
        
        // 更新最高分
        if (score > highScore) {
            highScore = score;
            saveHighScore(highScore);
        }
    }
    
    // 加载最高分
    private int loadHighScore() {
        // 实际应用中可以从文件或数据库加载
        return 0;
    }
    
    // 保存最高分
    private void saveHighScore(int score) {
        // 实际应用中可以保存到文件或数据库
    }
    
    // 开始新游戏
    public void startNewGame() {
        score = 0;
        gameOver = false;
        initializeGame();
    }
    
    // 获取游戏网格
    public int[][] getGrid() {
        return grid;
    }
    
    // 获取当前方块
    public Block getCurrentBlock() {
        return currentBlock;
    }
    
    // 获取下一个方块
    public Block getNextBlock() {
        return nextBlock;
    }
    
    // 获取当前分数
    public int getScore() {
        return score;
    }
    
    // 获取最高分
    public int getHighScore() {
        return highScore;
    }
    
    // 检查游戏是否结束
    public boolean isGameOver() {
        return gameOver;
    }
    
    // 获取游戏区域宽度
    public int getWidth() {
        return width;
    }
    
    // 获取游戏区域高度
    public int getHeight() {
        return height;
    }
}
